from flask import Flask, request, url_for
from flask_restful import Api, Resource, reqparse, fields, marshal_with

app = Flask(__name__)

api = Api(app)  # 初始化得到 api 对象


class HelloRESTful(Resource):
    def get(self):
        return {'greet': 'Hello Flask RESTful!'}

# 初始化待办列表
todos = {
  'todo_1': "读《程序员的自我修养》",
  'todo_2': "买点吃的",
  'todo_3': "去看星星"
}


class Todo(Resource):
    # 根据 todo_id 获取代办事项
    def get(self, todo_id):
        return { todo_id: todos[todo_id] }

    # 新增一个待办事项
    def put(self, todo_id):
        todos[todo_id] = request.form['data']
        return {todo_id: todos[todo_id]}


class Todo1(Resource):
    def get(self):
        # 直接返回
        return { 'task': 'Hello world'}

class Todo2(Resource):
    def get(self):
        # 返回内容及状态码
        return {'task': 'Hello world'}, 201

class Todo3(Resource):
    def get(self):
        # 返回内容，状态码以及 Header
        return {'task': 'Hello world'}, 200, {'Etag': 'some-opaque-string'}

parser = reqparse.RequestParser()  # 定义全局的解析实体
# 定义参数 id，类型必须是整数
parser.add_argument('id', type=int, help='必须提供参数 id')
# 定义参数 name，且为必填
parser.add_argument('name', required=True)
parser_copy = parser.copy()  # 继承
parser_copy.add_argument('bar', type=int)  # parser_copy 将有两个参数
# 改变继承来的参数 foo 必填且的获取位置为 querystring
parser_copy.replace_argument('foo', required=True, location='args')
# 删除继承来的参数 foo
parser_copy.remove_argument('foo')
# ...

class Reqparser(Resource):
    def get(self):
        args = parser.parse_args()  # 获取解析器中定义的参数 并校验
        return args

resource_fields = {
    'name': fields.String,
    'address': fields.String,
    'date_updated': fields.DateTime(dt_format='rfc822'),
}

# fields = {
#     # name 将被重命名为 private_name
#     'name': fields.String(attribute='private_name'),
#     'address': fields.String
# }

fields = {
    # 为 name 设置默认值
    'name': fields.String(default='Anonymous User'),
    'address': fields.String
}


def db_get_todo():
    return fields.keys()


class TodoFormat(Resource):
    @marshal_with(fields, envelope='resource')
    def get(self):
        return db_get_todo()  # 某个获得待办事项的方法



api.add_resource(HelloRESTful, '/')
api.add_resource(Todo, '/todo/<string:todo_id>/')
# 端点与视图函数同名，但是你也可以修改它  端点通常用作反向查询URL地址（viewfunction-->endpoint-->URL）
api.add_resource(Todo1, '/todo_1/', endpoint='todo_ep')
# api.add_resource(Todo, '/todo_1/', endpoint='todo_ep')
api.add_resource(Todo2, '/todo_2/')
# 多视图
api.add_resource(Todo3, '/todo_3/', '/my/todo_3/')

api.add_resource(Reqparser, '/reqparser/')
api.add_resource(TodoFormat, '/todo_format/')

with app.test_request_context('/'):
    print(url_for('todo_ep'))  # /todo_1/

'''
详细api文档：https://flask-restful.readthedocs.io/en/latest/
'''
if __name__ == '__main__':
    app.run(debug=True)